<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>候选词概率可视化 V20250417</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
    <style>
        .container {
            display: flex;
            flex-direction: column;
            align-items: center;
            margin-top: 20px;
        }
        .controls {
            margin-bottom: 20px;
        }
        .chart {
            width: 97%;
            height: 300px;
        }
        table {
            width: 97%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: center;
        }
        th {
            background-color: #f2f2f2;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="controls">
        <label for="temperature">Temperature:</label>
        <input type="number" id="temperature" value="0.7" step="0.1" min="0.1" max="2.0">
        <label for="topK">TopK:</label>
        <input type="number" id="topK" value="5" step="1" min="1" max="10">
        <label for="topP">TopP:</label>
        <input type="number" id="topP" value="0.8" step="0.05" min="0.1" max="1.0">
    </div>
    <div class="chart" id="chart"></div>

    <!-- 添加表格 -->
    <table id="data-table">
        <thead>
        <tr>
            <th></th>
            <th>词1</th>
            <th>词2</th>
            <th>词3</th>
            <th>词4</th>
            <th>词5</th>
            <th>词6</th>
            <th>词7</th>
            <th>词8</th>
            <th>词9</th>
        </tr>
        </thead>
        <tbody>
        <!-- 数据行将通过 JavaScript 动态插入 -->
        </tbody>
    </table>
</div>

<script>
    // 初始数据
    const initialProbabilities = [0.26, 0.24, 0.15, 0.14, 0.1, 0.08, 0.01, 0.01, 0.01];
    const words = ['词1', '词2', '词3', '词4', '词5', '词6', '词7', '词8', '词9'];

    // 初始化图表
    const chart = echarts.init(document.getElementById('chart'));

    function updateCharts() {
        const temperature = parseFloat(document.getElementById('temperature').value);
        const topK = parseInt(document.getElementById('topK').value);
        const topP = parseFloat(document.getElementById('topP').value);

        // 原始词概率
        const originalProbabilities = initialProbabilities.slice();

        // Temperature 调整后的词概率
        const temperatureAdjusted = originalProbabilities.map(prob => Math.pow(prob, 1 / temperature));
        const temperatureSum = temperatureAdjusted.reduce((a, b) => a + b, 0);
        const temperatureNormalized = temperatureAdjusted.map(prob => prob / temperatureSum);

        // TopK 调整后的词概率
        const topKAdjusted = [...temperatureNormalized].sort((a, b) => b - a).slice(0, topK);
        const topKSum = topKAdjusted.reduce((a, b) => a + b, 0);
        const topKNormalized = topKAdjusted.map(prob => prob / topKSum);

        // TopP 调整后的词概率 (基于 TopK 调整后的词概率)
        let cumulativeProb = 0;
        const topPAdjusted = [];
        for (let i = 0; i < topKNormalized.length; i++) {
            cumulativeProb += topKNormalized[i];
            topPAdjusted.push(topKNormalized[i]);
            if (cumulativeProb >= topP) break;
        }
        const topPSum = topPAdjusted.reduce((a, b) => a + b, 0);
        const topPNormalized = topPAdjusted.map(prob => prob / topPSum);

        // 更新图表
        updateChart(originalProbabilities, temperatureNormalized, topKNormalized, topPNormalized, topK, topP);

        // 更新表格
        updateTable(originalProbabilities, temperatureNormalized, topKNormalized, topPNormalized);
    }

    function updateChart(originalData, temperatureData, topKData, topPData, topK, topP) {
        const seriesData = words.map((word, index) => ({
            name: word,
            type: 'bar',
            stack: 'total',
            data: [topPData[index] || 0, topKData[index] || 0, temperatureData[index] || 0, originalData[index] || 0],
            label: {
                show: true,
                position: 'inside',
                formatter: function (params) {
                    return params.value.toFixed(2);
                }
            }
        }));

        const option = {
            title: {
                text: '候选词概率可视化 V20250417',
                left: 'center'
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            legend: {
                data: words,
                orient: 'horizontal',
                bottom: '0'
            },
            xAxis: {
                type: 'value',
                max: 1
            },
            yAxis: {
                type: 'category',
                data: ['TopP\n调整后的词概率\n取前'+topP+'的数据', 'TopK\n调整后的词概率\n取前'+topK+'个结果', 'Temperature\n调整后的词概率\n拉大差距', '原始词概率']
            },
            series: seriesData
        };
        chart.setOption(option);
    }

    function updateTable(originalData, temperatureData, topKData, topPData) {
        const tableBody = document.querySelector('#data-table tbody');
        tableBody.innerHTML = ''; // 清空表格内容

        // 构造新的表格行
        const rows = [
            { title: '原始词概率', data: originalData },
            { title: 'Temperature 调整后的词概率', data: temperatureData },
            { title: 'TopK 调整后的词概率', data: topKData },
            { title: 'TopP 调整后的词概率', data: topPData }
        ];

        rows.forEach(rowData => {
            const row = document.createElement('tr');
            row.innerHTML = `
                <td>${rowData.title}</td>
                ${words.map((word, index) => `<td>${(rowData.data[index] || 0).toFixed(2)}</td>`).join('')}
            `;
            tableBody.appendChild(row);
        });
    }

    // 初始化图表
    updateCharts();

    // 监听输入框变化
    document.getElementById('temperature').addEventListener('input', updateCharts);
    document.getElementById('topK').addEventListener('input', updateCharts);
    document.getElementById('topP').addEventListener('input', updateCharts);
</script>
</body>
</html>
